<?php


namespace App\Utility;


use App\Model\UserModel;
use EasySwoole\Component\Singleton;
use EasySwoole\HttpClient\Exception\InvalidUrl;
use EasySwoole\HttpClient\HttpClient;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\Utility\Str;
use Endroid\QrCode\QrCode as QrcodeLib;
use Throwable;

/**
 * 数据转换工具
 * Class DataConversion
 * @package App\Utility
 */
class DataConversion
{
    use Singleton;

    /**
     * 将数组中下划线样式的键转换为驼峰式的键
     * @param array $data
     * @return array
     */
    public function convertToHump(array $data): array
    {
        return self::convert($data, array($this, 'hump'));
    }

    /**
     * 将数组中驼峰样式的键转换为下划线的键
     * @param array $data
     * @return array
     */
    public function convertToUnderline(array $data): array
    {
        return self::convert($data, array($this, 'underline'));
    }

    /**
     * 下划线转驼峰(首字母小写)
     * @param string $value
     * @return string
     */
    public function hump(string $value): string
    {
        return Str::camel($value);
    }

    /**
     * 驼峰转下划线
     * @param string $value
     * @return string
     */
    public function underline(string $value): string
    {
        return Str::snake($value);
    }

    private function convert(array $data, $func): array
    {
        $tempArray = array();
        foreach ($data as $key => $value) {
            $key = $func($key);
            if (is_array($value)) {
                $value = self::convert($value, $func);
            }
            $tempArray[$key] = $value;
        }
        return $tempArray;
    }

    /**
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function get_random($length = 8): int
    {
        $min = pow(10, ($length - 1));

        $max = pow(10, $length) - 1;

        $userid = mt_rand($min, $max);
        $user = UserModel::create()->getUser(['userid' => $userid]);
        if ($user) $userid = $this->get_random(8);
        return $userid;
    }

    /**
     * @return string
     */
    public function get_order_no(): string
    {
        $time = date("YmdHis", time());
        $num = rand(10000, 99999);
        return $time . $num;
    }

    public function arraySort($array, $keys, $sort = 'asc'): array
    {
        $newArr = $valArr = array();
        foreach ($array as $key => $value) {
            $valArr[$key] = $value[$keys];
        }
        ($sort == 'asc') ? asort($valArr) : arsort($valArr);
        reset($valArr);
        foreach ($valArr as $key => $value) {
            $newArr[$key] = $array[$key];
        }
        $data = [];
        foreach ($newArr as $arr) {
            $data[] = $arr;
        }
        return $data;
    }

    public function timeToDate($t)
    {
        $time = time();
        $t = intval($t);
        if (date('Y-m-d', $time) == date('Y-m-d', $t)) {
            $time1 = date("H:i:s", $t);
        } else {
            $time1 = date('y-m-d', $t);
        }
        return $time1;
    }

    public function birthday($birthday)
    {
        $age = strtotime($birthday);
        if ($age === false) {
            return 0;
        }
        list($y1, $m1, $d1) = explode("-", date("Y-m-d", $age));
        $now = strtotime("now");
        list($y2, $m2, $d2) = explode("-", date("Y-m-d", $now));
        $age = $y2 - $y1;
        if ((int)($m2 . $d2) < (int)($m1 . $d1))
            $age -= 1;
        return $age;
    }

    /**
     * @param $arr
     * @return bool
     */
    public function checkArrayRecover($arr): bool
    {
        if (count($arr) != count(array_unique($arr))) {
            return false;
        }
        return true;
    }

    /**
     * @return false|string
     */
    public function shufflerRequestId()
    {
        $permitted_chars = '0123456789#abcdefghilkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        return substr(str_shuffle($permitted_chars), 0, 16);
    }

    /**
     * @param $length
     * @return false|string
     */
    public function shufflerCode($length)
    {
        $permitted_chars = '0123456789#abcdefghilkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        return substr(str_shuffle($permitted_chars), 0, $length);
    }

    /**
     * @param $ip
     * @return mixed
     * @throws InvalidUrl
     */
    public function ip_address($ip)
    {
        $durl = 'https://ip.taobao.com/outGetIpInfo?ip=' . $ip . '&accessKey=alibaba-inc';
        $client = new HttpClient($durl);
        $client->setUrl($durl);
        $client->setQuery(['ip' => $ip, 'accessKey' => 'alibaba-inc']);
        $response = $client->get();
        return $response->getBody();
    }

    public function getSubNum($str)
    {
        $str = trim($str);
        if (empty($str)) {
            return '';
        }
        $reg = '/(\d{3}(\.\d+)?)/is';//匹配数字的正则表达式
        preg_match_all($reg, $str, $result);
        if (is_array($result) && !empty($result) && !empty($result[1]) && !empty($result[1][0])) {
            return $result[1][0];
        }
        return 0;
    }

    /**
     * php获取中文字符拼音首字母
     * @param $str
     * @return null|string
     */
    public function getFirstCharter($str)
    {
        if (empty($str)) {
            return 0;
        }

        try {
            $str = mb_substr($str, 0, 1);
            $fchar = ord($str[0]);
            if ($fchar >= ord('A') && $fchar <= ord('z')) return strtoupper($str[0]);
            $s1 = iconv('UTF-8', 'GBK//TRANSLIT//IGNORE', $str);
            $s2 = iconv('GBK', 'UTF-8//TRANSLIT//IGNORE', $s1);
            $s = $s2 == $str ? $s1 : $str;
            if (!isset($s[1]) || !isset($s[0])) {
                return 0;
            }
            $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
            if ($asc >= -20319 && $asc <= -20284) return 'A';
            if ($asc >= -20283 && $asc <= -19776) return 'B';
            if ($asc >= -19775 && $asc <= -19219) return 'C';
            if ($asc >= -19218 && $asc <= -18711) return 'D';
            if ($asc >= -18710 && $asc <= -18527) return 'E';
            if ($asc >= -18526 && $asc <= -18240) return 'F';
            if ($asc >= -18239 && $asc <= -17923) return 'G';
            if ($asc >= -17922 && $asc <= -17418) return 'H';
            if ($asc >= -17417 && $asc <= -16475) return 'J';
            if ($asc >= -16474 && $asc <= -16213) return 'K';
            if ($asc >= -16212 && $asc <= -15641) return 'L';
            if ($asc >= -15640 && $asc <= -15166) return 'M';
            if ($asc >= -15165 && $asc <= -14923) return 'N';
            if ($asc >= -14922 && $asc <= -14915) return 'O';
            if ($asc >= -14914 && $asc <= -14631) return 'P';
            if ($asc >= -14630 && $asc <= -14150) return 'Q';
            if ($asc >= -14149 && $asc <= -14091) return 'R';
            if ($asc >= -14090 && $asc <= -13319) return 'S';
            if ($asc >= -13318 && $asc <= -12839) return 'T';
            if ($asc >= -12838 && $asc <= -12557) return 'W';
            if ($asc >= -12556 && $asc <= -11848) return 'X';
            if ($asc >= -11847 && $asc <= -11056) return 'Y';
            if ($asc >= -11055 && $asc <= -10247) return 'Z';
            return 0;
        } catch (\Exception $exception) {
            return 0;
        }
    }

    /**
     * 影藏手机号中间四位
     * @param $phone
     * @return array|string|string[]|null
     */
    public function hidtel($phone)
    {
        $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i', $phone); //固定电话
        if ($IsWhat == 1) {
            return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i', '$1****$2', $phone);
        } else {
            return preg_replace('/(1[356789]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $phone);
        }
    }

    /**
     * @param $avatar
     * @param $code
     * @return string
     */
    public function setQrCode($avatar, $code): string
    {
        $qrCode = new QrcodeLib();
        $qrCode->setText($code);
        $qrCode->setLogoPath($avatar);
        $qrCode->setLogoSize(32, 32);
        $qrCode->setSize(200);
        $qrCode->setBackgroundColor(['r' => 255, 'g' => 218, 'b' => 185, 'a' => 50]);
        return $qrCode->writeDataUri();
    }

    /**
     * 获取天数
     * @param $start
     * @param $end
     * @return float|int
     */
    public function getDays($start, $end)
    {
        $time = $end - $start;
        return $time / 86400;
    }

    /**
     * 获取某月天数
     * @param $year
     * @param $month
     * @return int
     */
    public function getMothDay($year, $month): int
    {

        switch ($month) {

            case 1:

            case 3:

            case 5:

            case 7:

            case 8:

            case 10:

            case 12:

                $day = 31;

                break;

            case 2:

                $day = (intval($year % 4) ? 28 : 29); //能被4除尽的为29天其他28天

                break;

            default:

                $day = 30;

                break;

        }

        return $day;

    }
}
